package com.xscha.tableforge.listener;

import com.xscha.soyue.common.core.utils.JsonUtils;
import com.xscha.tableforge.model.entity.OperationLog;
import com.xscha.tableforge.service.OperationLogService;
import com.xscha.tableforge.utils.SecurityUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.jooq.Record;
import org.jooq.RecordContext;
import org.jooq.RecordListener;
import org.jooq.RecordListenerProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;

@Component
public class TableOperationListener implements RecordListener, RecordListenerProvider {

    private static final Logger logger = LoggerFactory.getLogger(TableOperationListener.class);

    @Autowired
	@Lazy
    private OperationLogService operationLogService;

    @Override
    public void insertStart(RecordContext ctx) {
        logOperation(ctx.record(), "INSERT");
    }

    @Override
    public void updateStart(RecordContext ctx) {
        logOperation(ctx.record(), "UPDATE");
    }

    @Override
    public void deleteStart(RecordContext ctx) {
        logOperation(ctx.record(), "DELETE");
    }

    @Override
    public void insertEnd(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void updateEnd(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void deleteEnd(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void loadStart(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void loadEnd(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void refreshStart(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void refreshEnd(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void storeStart(RecordContext ctx) {
        // 不需要实现
    }

    @Override
    public void storeEnd(RecordContext ctx) {
        // 不需要实现
    }

    private void logOperation(Record record, String operationType) {
        try {
            if (record == null) {
                logger.warn("Attempted to log operation with null record");
                return;
            }

            // 获取记录的所有字段
            Map<String, Object> recordMap = record.intoMap();
            logger.debug("Record data: {}", recordMap);

            OperationLog log = new OperationLog();
            log.setId(UUID.randomUUID().toString().replace("-", ""));
            log.setUserId(SecurityUtils.getUserId());
            log.setSpaceId(SecurityUtils.getCurrentSpaceId());

            // 从表名中获取表ID
			String tableId = record.get("table_id", String.class);
            String recordId = record.getValue("id", String.class);

            if (recordId == null) {
                logger.warn("Missing required field: recordId");
                return;
            }

            log.setTableId(tableId);  // 使用表名作为tableId
            log.setRecordId(recordId);
            log.setOperationType(operationType);

            try {
                log.setNewData(JsonUtils.toJsonString(recordMap));
            } catch (Exception e) {
                logger.error("Failed to serialize record data", e);
                log.setNewData("{}");
            }

            // 获取请求信息
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                log.setIp(getClientIp());
                log.setUserAgent(request.getHeader("User-Agent"));
            }

            log.setCreatedTime(LocalDateTime.now());

            operationLogService.save(log);
            logger.debug("Successfully logged operation: {} for record: {} in table: {}",
                    operationType, recordId, tableId);
        } catch (Exception e) {
            logger.error("Failed to log operation", e);
        }
    }

    private String getClientIp() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return "unknown";
        }
        
        HttpServletRequest request = attributes.getRequest();
        String[] headers = {
            "X-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_CLIENT_IP",
            "HTTP_X_FORWARDED_FOR"
        };

        for (String header : headers) {
            String ip = request.getHeader(header);
            if (ip != null && ip.length() > 0 && !"unknown".equalsIgnoreCase(ip)) {
                return ip;
            }
        }

        return request.getRemoteAddr();
    }

    @Override
    public RecordListener provide() {
        return this;
    }
} 